package com.yt.order.api.client;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.internal.util.StringUtils;
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.yt.common.constant.Result;
import com.yt.common.enums.CodeEnum;
import com.yt.order.common.config.AlipayConfig;
import com.yt.order.common.config.YmlConfig;
import com.yt.order.models.bo.PayBO;
import com.yt.order.models.bo.WorkOrderInfoBO;
import com.yt.order.models.bo.WorkOrderInfoSaveBO;
import com.yt.order.models.dto.*;
import com.yt.order.models.service.*;
import com.yt.order.models.vo.WorkOrderInfoVO;
import com.yt.product.models.dto.ProductInfoDTO;
import com.yt.product.models.service.IProductInfoService;
import com.yt.user.models.dto.CustomerInfoDTO;
import com.yt.user.models.service.ICustomerInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 系统权限信息控制器
 *
 * @author zhou
 * @Date 2025-09-06 10:41:50
 */

@RestController
@RequestMapping("/api/workOrderInfo")
@Slf4j
@Api(value = "WorkOrderInfoApiController", tags = "工单信息Api接口")
public class WorkOrderInfoApiController {

    @DubboReference
    private IWorkOrderInfoService workOrderInfoService;
    long change = 0;
    @DubboReference
    private IProductInfoService productInfoService;
    @DubboReference
    private IEmpRetreatService empRetreatService;
    @Resource
    private YmlConfig ymlConfig;
    @DubboReference
    private ICustomerInfoService customerInfoService;
    @PostMapping("/deleteEmployee")
    @ApiOperation(value = "根据id删除员工工单", notes = "根据id删除员工工单")
    @ApiImplicitParam(name = "id", value = "id", required = true, paramType = "query", dataType = "Long")
    public Result<Boolean> deleteEmployee(@RequestParam("id") Long id) {
        if (id == null) {
            return new Result<>(CodeEnum.FAIL_100002);
        }
        //删除员工id，状态改为待接单,往员工退单表插入数据
        boolean flag = workOrderInfoService.deleteEmployeeOrder(id);
        return new Result<>(flag);
    }
    @PostMapping("/updateStatus")
    @ApiOperation(value = "根据id修改工单状态",notes = "根据id修改工单状态")
    @ApiImplicitParam(name = "id", value = "id", required = true, paramType = "query", dataType = "Long")
    public Result<Boolean> updateStatus(@RequestParam("id") Long id) {
        if (id == null) {
            return new Result<>(CodeEnum.FAIL_100002);
        }
        WorkOrderInfoDTO wor = workOrderInfoService.selectById(id);
        wor.setStatus(1);
        boolean flag=workOrderInfoService.updateById(wor);
        return new Result<>(flag);
    }


    @ApiOperation(value = "分页查询工单列表", notes = "支持按状态、时间范围、类型等条件筛选，返回分页数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNo", value = "页码，从1开始", paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "status", value = "状态（0待接单 1已接单 2处理中）", paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "id", value = "工单iD", paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "priority", value = "优先级(1低，2中，3高)", paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "payStatus", value = "支付状态(0未支付，1支付，2免费)", paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "employeeId", value = "员工iD", paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name="customerId",value = "客户id",paramType = "query",dataType ="Integer" ),
            @ApiImplicitParam(name="retreatId",value = "退单员工id",paramType = "query",dataType ="Integer" )
    })
    @PostMapping("/queryWorkOrderPageList")
    public Result<Page<WorkOrderInfoVO>> queryWorkOrderPageList(WorkOrderInfoBO bo) {
        // 验证分页参数
        if (bo.getPageNo() == null || bo.getPageNo() < 1) {
            bo.setPageNo(1);
        }
        if (bo.getPageSize() == null || bo.getPageSize() < 1 || bo.getPageSize() > 100) {
            bo.setPageSize(10);
        }

        // 构建查询条件
        Wrapper<WorkOrderInfoDTO> wrapper = new EntityWrapper<>();
        //查询员工退单表所有工单id
        List<Long> retreatIdList=empRetreatService.queryRetreat(bo.getRetreatId());
        if (retreatIdList != null && retreatIdList.size() > 0) {
            wrapper.notIn("id", retreatIdList);
        }
        //员工id查询
        if (bo.getEmployeeId() != null) {
            wrapper.eq("employee_id", bo.getEmployeeId());
        }
        //客户id查询
        if (bo.getCustomerId()!=null){
            wrapper.eq("customer_id", bo.getCustomerId());
        }
        //支付状态筛选
        if (bo.getPayStatus() != null) {
            wrapper.eq("pay_status", bo.getPayStatus()); // 假设数据库字段为pay_status
        }
        // 状态筛选
        if (bo.getStatus() != null) {
            wrapper.eq("status", bo.getStatus());
        }

        // 新增类型筛选条件
        if (bo.getType() != null) {
            wrapper.eq("type", bo.getType());
        }

        // 新增工单ID筛选条件（模糊查询）
        if (bo.getId() != null) {
            // 将bigint类型的id转换为字符串后再进行模糊匹配
            wrapper.like("CAST(id AS CHAR)", String.valueOf(bo.getId()));
        }
        // 工单标题筛选条件（模糊查询）
        if (bo.getTitle() != null) {
            wrapper.like("title", bo.getTitle());
        }
        // 客户地址筛选条件（模糊查询）
        if (bo.getAddress() != null) {
            wrapper.like("address", bo.getAddress());
        }
        // 优先级筛选条件
        if (bo.getPriority() != null) {
            wrapper.eq("priority", bo.getPriority());
        }

        // 按创建时间倒序排列
        wrapper.orderBy("create_time", false);

        // 执行分页查询
        Page<WorkOrderInfoDTO> dtoPage = new Page<>(bo.getPageNo(), bo.getPageSize());
        dtoPage = workOrderInfoService.selectPage(dtoPage, wrapper);

        // 转换DTO为VO
        Page<WorkOrderInfoVO> voPage = new Page<>();
        BeanUtils.copyProperties(dtoPage, voPage);

        List<WorkOrderInfoVO> voList = dtoPage.getRecords().stream()
                .map(dto -> {
                    WorkOrderInfoVO vo = new WorkOrderInfoVO();
                    BeanUtils.copyProperties(dto, vo);
                    // 处理pic字段：将逗号分隔的字符串转换为列表
                    String picStr = dto.getPic();  // 获取DTO中的pic字符串
                    if (picStr != null && !picStr.isEmpty()) {
                        // 按逗号分割，同时处理可能的空格（如"url1, url2"）
                        List<String> picList = Arrays.stream(picStr.split(","))
                                .map(String::trim)  // 去除每个URL的前后空格
                                .filter(s -> !s.isEmpty())  // 过滤空字符串（避免分割后出现空元素）
                                .collect(Collectors.toList());
                        vo.setPicList(picList);
                    } else {
                        // 如果原字符串为空，设置为空列表（避免null）
                        vo.setPicList(Collections.emptyList());
                    }
                    return vo;
                })
                .collect(Collectors.toList());

        voPage.setRecords(voList);

        return new Result<>(voPage);
    }

    @PostMapping("/updateemployeeorder")
    @ApiOperation(value = "修改员工端订单", notes = "修改员工端订单")
    @Transactional
    public Result<Boolean> updateemployeeorder(@RequestBody WorkOrderInfoSaveBO saveBO) {
        if (saveBO == null) {
            return new Result<>(CodeEnum.FAIL_100002);
        }
        //有传产品id就修改产品id和产品数量才修改
        if (saveBO.getProductId() != null) {
            // 通过订单id判断订单是否存在，存在vo的内容是数据库中的内容
            WorkOrderInfoVO vo = workOrderInfoService.getworkOrderInfoVOById(saveBO);
            if (vo == null) {
                return new Result<>(CodeEnum.FAIL_ORDER_300000);
            }
            Wrapper<WorkOrderInfoDTO> wrapper = new EntityWrapper<>();
            wrapper.eq("id", saveBO.getId());
            WorkOrderInfoDTO dto = workOrderInfoService.selectOne(wrapper);
            // 产品id不变
            if (Objects.equals(dto.getProductId(), saveBO.getProductId())) {
                // 产品id不变，数量变了（原来数量-更改数量）
                change = saveBO.getProductQuantity() - dto.getProductQuantity();
                //查询产品信息表
                Wrapper<ProductInfoDTO> wrapper1 = new EntityWrapper<>();
                wrapper1.eq("id", dto.getProductId());
                ProductInfoDTO productInfoDTO = productInfoService.selectOne(wrapper1);
                //更改产品信息表的库存
                productInfoDTO.setStock(productInfoDTO.getStock() - change);
                //库存不够会报错
                if (productInfoDTO.getStock() < 0) {
                    return new Result<>(CodeEnum.FAIL_100008);
                }
                productInfoService.updateById(productInfoDTO);
            } else {
                // 产品id变了：原来库存加上原来数量
                Wrapper<ProductInfoDTO> wrapper1 = new EntityWrapper<>();
                wrapper1.eq("id", dto.getProductId());
                ProductInfoDTO productInfoDTO = productInfoService.selectOne(wrapper1);
                productInfoDTO.setStock(productInfoDTO.getStock() + dto.getProductQuantity());
                productInfoService.updateById(productInfoDTO);

                //减去更改产品id的库存
                Wrapper<ProductInfoDTO> wrapper2 = new EntityWrapper<>();
                wrapper2.eq("id", saveBO.getProductId());
                ProductInfoDTO productInfoDTO2 = productInfoService.selectOne(wrapper2);
                productInfoDTO2.setStock(productInfoDTO2.getStock() - saveBO.getProductQuantity());

                //库存不够会报错
                if (productInfoDTO2.getStock() < 0) {
                    return new Result<>(CodeEnum.FAIL_100008);
                }

                productInfoService.updateById(productInfoDTO2);
            }
        }

        //更新工单
        boolean falg = workOrderInfoService.updateById(saveBO);
        // 补充返回语句（成功场景）
        return new Result<>(falg);
    }

    @PostMapping("/takeEmployee")
    @ApiOperation(value = "员工接单", notes = "员工接单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "employeeId", value = "员工id", required = true, paramType = "query", dataType = "Long")
    })
    public Result<Boolean> receiveOrder(@RequestParam("id") Long id, @RequestParam("employee_id") Long employeeId) {
        if (id == null || employeeId == null) {
            return new Result<>(CodeEnum.FAIL_100002);
        }
        WorkOrderInfoDTO workOrderInfoDTO = workOrderInfoService.selectById(id);
        //不存在报错
        if (workOrderInfoDTO == null) {
            return new Result<>(CodeEnum.FAIL_100002);
        }
        //存在设置员工id
        workOrderInfoDTO.setEmployeeId(employeeId);
        //将状态改变为处理中
        workOrderInfoDTO.setStatus(2);
        //更新数据库
        boolean flag = workOrderInfoService.updateById(workOrderInfoDTO);

        return new Result<>(flag);
    }

    @DubboReference
    private IAlipayService alipayService;
    @Resource
    private AlipayConfig alipayConfig;


    /**
     * 发起支付宝支付
     */
    @PostMapping("/createAlipay")
    @ApiOperation(value = "发起支付宝支付", notes = "根据工单ID创建支付订单")
    public Result<String> createAlipay(@RequestBody PayBO payBO) {

        return alipayService.createPayOrder(payBO);
    }
    /**
     * 支付宝异步通知接收与签名验证
     */
    // 在 WorkOrderInfoApiController.java 的 handleNotify 方法中
    // 支付宝异步通知接口（对应alipay.notify-url配置）

    @PostMapping("/notify")
    public String notify(HttpServletRequest request, @RequestParam Map<String, String> params) {
        try {
            // 1. 验证签名
            boolean signVerified = AlipaySignature.rsaCheckV1(
                    params,
                    alipayConfig.getPublicKey(),
                    "UTF-8",
                    "RSA2"
            );

            // 2. 签名验证失败
            if (!signVerified) {
                // 记录恶意请求日志
                System.out.println("支付宝异步通知签名验证失败");
                return "fail";
            }

            // 3. 签名验证成功，处理业务逻辑
            System.out.println("支付宝异步通知签名验证成功");

            // 4. 验证通知数据中的支付状态
            String tradeStatus = params.get("trade_status");
            // 交易成功的状态
            if ("TRADE_SUCCESS".equals(tradeStatus)) {
                // 获取订单号
                String outTradeNo = params.get("out_trade_no");
                // 获取支付宝交易号
                String tradeNo = params.get("trade_no");
                // 获取支付金额
                String totalAmount = params.get("total_amount");

                // 5. 修改支付状态和工单状态
                Wrapper<WorkOrderInfoDTO> wrapper = new EntityWrapper<>();
                wrapper.eq("id", outTradeNo);
                WorkOrderInfoDTO workOrderInfoDTO = workOrderInfoService.selectOne(wrapper);
                workOrderInfoDTO.setStatus(1);
                workOrderInfoDTO.setPayStatus(1);
                workOrderInfoService.updateById(workOrderInfoDTO);
                // 6. 返回处理结果
                return "success";
            } else {
                // 非支付成功状态，无需处理
                return "success";
            }

        } catch (AlipayApiException e) {
            e.printStackTrace();
            return "fail";
        }
    }
    @PostMapping("/EmpStatistic")
    @ApiOperation(value = "员工收益统计" ,notes = "员工收益统计")
    public Result<Map<String, Integer>> EmpStatistic(@RequestParam("empId") Long empId) {
        Map<String,Integer> map = new HashMap<>();
        //月收益和日收益
        int totalMoney=0;
        int dayMoney=0;
        Wrapper<WorkOrderInfoDTO> wrapper = new EntityWrapper<>();
        wrapper.eq("employee_id", empId)
                .eq("status", 1)
                .eq("is_evaluation",0);
        List<WorkOrderInfoDTO> workOrderInfoDTOS = workOrderInfoService.selectList(wrapper);
        for (WorkOrderInfoDTO workOrderInfoDTO : workOrderInfoDTOS) {
            CustomerInfoDTO customerInfoDTO=customerInfoService.selectById(workOrderInfoDTO.getCustomerId());
            //如果工单的用户是企业级用户价格是10元
            if(customerInfoDTO.getType()==1){
                totalMoney+=10;
            }
            else{
                //不是企业级用户且工单优先级高是8元
                if(workOrderInfoDTO.getType()==3){
                    totalMoney+=8;
                }
                //其他为5元
                else{
                    totalMoney+=5;
                }
            }
        }
        // 1. 获取今天的开始时间（00:00:00）和结束时间（23:59:59）
        LocalDateTime todayStart = LocalDate.now().atStartOfDay(); // 今天0点
        LocalDateTime todayEnd = LocalDate.now().atTime(23, 59, 59, 999); // 今天23:59:59

        // 2. 转换为Date类型（根据数据库字段类型选择，若用LocalDateTime可直接使用）
        Date startDate = Date.from(todayStart.atZone(ZoneId.systemDefault()).toInstant());
        Date endDate = Date.from(todayEnd.atZone(ZoneId.systemDefault()).toInstant());
        Wrapper<WorkOrderInfoDTO> wrapper1 = new EntityWrapper<>();
        wrapper1.eq("employee_id", empId)
                .eq("status", 1)
                .eq("is_evaluation",0)
                .ge("update_time", startDate) // 大于等于今天0点
                .le("update_time", endDate);  // 小于等于今天23:59:59;
        List<WorkOrderInfoDTO> workOrderInfoDTO1 = workOrderInfoService.selectList(wrapper1);
        for (WorkOrderInfoDTO workOrderInfoDTO : workOrderInfoDTO1) {
            CustomerInfoDTO customerInfoDTO=customerInfoService.selectById(workOrderInfoDTO.getCustomerId());
            //如果工单的用户是企业级用户价格是10元
            if(customerInfoDTO.getType()==1){
                dayMoney+=10;
            }
            else{
                //不是企业级用户且工单优先级高是8元
                if(workOrderInfoDTO.getType()==3){
                    dayMoney+=8;
                }
                //其他为5元
                else{
                    dayMoney+=5;
                }
            }
        }

        map.put("totalMoney",totalMoney);
        map.put("dayMoney",dayMoney);
        return new Result<>(map);
    }
}
